#ifndef A_CIF_DATA_LOADER_H
#define A_CIF_DATA_LOADER_H

#include <stdio.h>
#include "CifData.h"

#define CIF_PATTERN_COMMENT_HASH                             ("#")
#define CIF_PATTERN_SAVE_FRAME_LINK                          ("$")
#define CIF_PATTERN_COMPLEX_DATA_VALUE_APOSTROPHE            ("'")
#define CIF_PATTERN_COMPLEX_DATA_VALUE_QUOTES                ("\"")
#define CIF_PATTERN_COMPLEX_DATA_VALUE_OPENING_SQUARE_BRAKET ("[")
#define CIF_PATTERN_COMPLEX_DATA_VALUE_CLOSING_SQUARE_BRAKET ("]")
#define CIF_PATTERN_COMPLEX_DATA_VALUE_SEMICOLON             (";")
#define CIF_PATTERN_DATA_BLOCK                               ("data_")
#define CIF_PATTERN_SAVE_FRAME                               ("save_")
#define CIF_PATTERN_LOOP                                     ("loop_")
#define CIF_PATTERN_STOP                                     ("stop_")
#define CIF_PATTERN_GLOBAL                                   ("global_")
#define CIF_PATTERN_DATA_ITEM                                ("_")

#define CIF_PATTERN_NUM_NO                                       (-2)
#define CIF_PATTERN_NUM_CONTINUE                                 (-1)
#define CIF_PATTERN_NUM_COMMENT_HASH                             (0)
#define CIF_PATTERN_NUM_SAVE_FRAME_LINK                          (1)
#define CIF_PATTERN_NUM_COMPLEX_DATA_VALUE_APOSTROPHE            (2)
#define CIF_PATTERN_NUM_COMPLEX_DATA_VALUE_QUOTES                (3)
#define CIF_PATTERN_NUM_COMPLEX_DATA_VALUE_OPENING_SQUARE_BRAKET (4)
#define CIF_PATTERN_NUM_COMPLEX_DATA_VALUE_CLOSING_SQUARE_BRAKET (5)
#define CIF_PATTERN_NUM_COMPLEX_DATA_VALUE_SEMICOLON             (6)
#define CIF_PATTERN_NUM_DATA_BLOCK                               (7)
#define CIF_PATTERN_NUM_SAVE_FRAME                               (8)
#define CIF_PATTERN_NUM_LOOP                                     (9)
#define CIF_PATTERN_NUM_STOP                                     (10)
#define CIF_PATTERN_NUM_GLOBAL                                   (11)
#define CIF_PATTERN_NUM_DATA_ITEM                                (12)

#define CIF_ERROR_CODE_OK                (0)
#define CIF_ERROR_CODE_FILE_OPEN_FAILED  (1)
#define CIF_ERROR_CODE_FILE_SYNTAX_ERROR (2)
#define CIF_ERROR_CODE_INTERNAL_ERROR    (3)

#define CIF_MAX_LINE_LENGTH              (2048)

/**
 * The ACifDataLoader class.
 * Loads file in CIF format.
 */
class ACifDataLoader
{

protected:

	/** 
     * The pointer to CIF file.
     */
	FILE *cifFile;

    /**
     * The pointer to CIF data.
	 * It's user's responsibility to free allocated memory for this object.
     */
	CifData *cifData;

    /** 
     * The error code of the last called function.
     */
	int errorCode;

    /**
     * Parses all data from an input file.
     */
	virtual void Parse() = 0;

	/**
	 * Prints error message to the stderr.
	 */
	virtual void PrintErrorMessage(char *msg);

	/**
	 * Returns 1 if end of file is reached.
	 */
	int IsEof();

public:

	/**
     * The constructor.
     * Initializes all members by-default.
     */
	ACifDataLoader();

	/**
     * The destructor.
     * Frees all used memory.
     */
	virtual ~ACifDataLoader();

    /**
     * Opens CIF-file for reading.
     * @param fileName A pointer to name of the input file.
     * @return Loaded data.
     */
	CifData *Load(const char *fileName);
};

#endif